#ifndef     __ERROR_H
#define     __ERROR_H

#include "../build.h"

namespace ec {

namespace pub {

constexpr uint8_t OK = 0x00;
constexpr uint8_t FLASH_ERR = 0x01;
constexpr uint8_t STORE_SUM_FAIL = 0x02;
constexpr uint8_t PARSE_ERR = 0x03;
constexpr uint8_t INVALID = 0x04;
constexpr uint8_t OTA_ID_INVALID = 0x05;
constexpr uint8_t OTA_MD5_INVALID = 0x06;
constexpr uint8_t OTA_PKG_INVALID = 0x07;

}

namespace main {

constexpr uint8_t DROP1_TIMEOUT = 0x11;
constexpr uint8_t DROP2_TIMEOUT = 0x12;
constexpr uint8_t PICK1_TIMEOUT = 0x13;
constexpr uint8_t PICK2_TIMEOUT = 0x14;
constexpr uint8_t PICK1_LOCKED = 0x15;
constexpr uint8_t PICK2_LOCKED = 0x16;
constexpr uint8_t FILM_NOT_CUP = 0x17;
constexpr uint8_t FILM_TIMEOUT = 0x18;
constexpr uint8_t STRAW_CLOSE_FAIL = 0x19;

}

namespace cargo {

constexpr uint8_t CARGO_ALM = 0x11;
constexpr uint8_t CARGO_TIMEOUT = 0x12;
constexpr uint8_t PICK_ALM = 0x13;
constexpr uint8_t PICK_TIMEOUT = 0x14;
constexpr uint8_t BOX_MOTOR_ALM = 0x15;
constexpr uint8_t BOX_MOTOR_TIMEOUT = 0x16;
constexpr uint8_t SCAN_TIMEOUT = 0x17;
constexpr uint8_t SCAN_FAIL = 0x18;
constexpr uint8_t COMPR_FAIL = 0x19;

}

namespace heat {

constexpr uint8_t STIR_MOTOR_ALM = 0x11;
constexpr uint8_t STIR_MOTOR_TIMEOUT = 0x12;

constexpr uint8_t HOLD_MOTOR_ALM = 0x13;
constexpr uint8_t HOLD_MOTOR_TIMEOUT = 0x14;

constexpr uint8_t FILM_MOTOR_ALM = 0x15;
constexpr uint8_t FILM_MOTOR_TIMEOUT = 0x16;

constexpr uint8_t FLOW_FAIL = 0x17;
constexpr uint8_t FLOW_TIMEOUT = 0x18;

}

namespace pearl {

constexpr uint8_t MOVE_MOTOR_ALM = 0x11;
constexpr uint8_t MOVE_MOTOR_TIMEOUT = 0x12;
constexpr uint8_t UPDOWN_MOTOR_ALM = 0x13;
constexpr uint8_t UPDOWN_MOTOR_TIMEOUT = 0x14;
constexpr uint8_t DUMP_MOTOR_ALM = 0x15;
constexpr uint8_t DUMP_MOTOR_TIMEOUT = 0x16;
constexpr uint8_t UPDOWN_IS_NOT_ORIGIN = 0x17;
constexpr uint8_t DUMP_IS_NOT_ORIGIN = 0x18;

}

}

struct Error {

    inline Error(uint8_t ec) : err_code(ec) {}
    inline Error() : err_code(ec::pub::OK) {}

    inline bool is_ok() const {
        return err_code == ec::pub::OK;
    }

    inline Error& operator=(uint8_t ec) {
        this->err_code = ec;
        return *this;
    }

    inline operator bool() const {
        return err_code != ec::pub::OK;
    }

    usize_t encode(uint8_t *buf) {
        buf[0] = err_code;
        return 1;
    }

    uint8_t err_code;
};


#endif
